package com.sf.tools.generate;
import java.io.File;
import java.util.ArrayList;
import java.util.List;

import com.sf.tools.common.Common;
import com.sf.tools.common.DBUtils;





public class BuildDao {

	private static StringBuffer buff = new StringBuffer();
	
	private static DBUtils dbUtils;
	
	private static boolean importDateUtil;
	private static boolean importLeftJoin;
	
	public static void createDao(DBUtils dbUtil){
		dbUtils = dbUtil;
		importDateUtil = false;
		importLeftJoin = false;
		
		createInterface();
		createClass();
//		System.out.println(buff.toString());
	}

	private static void importPackageIDao(){
		buff.append("package com.sf.module.").append(Common.MODULE_NAME).append(".dao;").append("\n\n");
		if(Common.EXPORT){
			buff.append("import java.util.List;").append("\n\n");
		}
		buff.append("import com.sf.framework.base.IPage;").append("\n")
			.append("import com.sf.framework.server.base.dao.IEntityDao;").append("\n")
			.append("import com.sf.module.").append(Common.MODULE_NAME).append(".domain.").append(Common.DOMAIN_NAME).append(";\n")
			.append("import com.sf.module.frameworkimpl.domain.QueryObj;").append("\n\n");
	}
	
	private static void importPackageDao(){
		buff.append("package com.sf.module.").append(Common.MODULE_NAME).append(".dao;").append("\n\n");
		if(Common.EXPORT){
			buff.append("import java.util.List;").append("\n\n");
		}
		buff.append("import org.apache.commons.lang.StringUtils;").append("\n");
		buff.append("IMPORT_DATEUTIL");
		buff.append("IMPORT_LEFT_JOIN");
		buff.append("import org.hibernate.criterion.DetachedCriteria;").append("\n")
			.append("import org.hibernate.criterion.Restrictions;").append("\n");
		if("注解".equals(Common.GENERATE_SPRING_TYPE)){
			buff.append("import org.springframework.stereotype.Repository;").append("\n");
		}
		buff.append("\n")
			.append("import com.sf.framework.base.IPage;").append("\n")
//			.append("import com.sf.framework.server.base.dao.BaseEntityDao;\n")
			.append("import com.sf.module.").append(Common.MODULE_NAME).append(".domain.").append(Common.DOMAIN_NAME).append(";\n")
			.append("import com.sf.module.frameworkimpl.domain.QueryObj;").append("\n");
	}
	
	private static void createInterface() {
		buff = new StringBuffer();
		importPackageIDao();
		buff.append(Common.getClassDesc(Common.DOMAIN_DESC+" Dao接口定义"))
			.append("public interface "+Common.IDAO_NAME+" extends IEntityDao<"+Common.DOMAIN_NAME+"> {\n\n")
			.append(Common.getMethodDesc("分页查询","queryObj"))
			.append("\t").append("public IPage<"+Common.DOMAIN_NAME+"> findPageBy(QueryObj queryObj);").append("\n\n");
		if(Common.EXPORT){
			buff.append(Common.getMethodDesc("导出","queryObj"));
			buff.append("\t").append("public List<"+Common.DOMAIN_NAME+"> listExport(QueryObj queryObj);").append("\n\n");
		}
		buff.append("}");
		
		
		File file = new File(Common.SAVE_PATH+File.separator+"dao");
		if(!file.exists()){
			file.mkdirs();
		}
		Common.write(new File(file,Common.IDAO_NAME+".java"), buff.toString());
		
		System.out.println(Common.IDAO_NAME+".java 已生成.....");
	}
	
	private static void createClass() {
		buff = new StringBuffer();
		importPackageDao();
		buff.append(Common.getClassDesc(Common.DOMAIN_DESC+" Dao接口实现"));
		if("注解".equals(Common.GENERATE_SPRING_TYPE)){
			buff.append("@Repository").append("\n");
		}
		buff.append("public class ").append(Common.DAO_NAME).append(" extends BaseEntityDao<").append(Common.DOMAIN_NAME).append("> implements ").append(Common.IDAO_NAME).append(" {\n\n");
		buff.append(create_Method_findPageBy());
		if(Common.EXPORT){
			buff.append(create_Method_list());
		}
		buff.append("}");
		
		String content = buff.toString();
		content = content.replace("IMPORT_LEFT_JOIN", importLeftJoin?"import org.hibernate.criterion.CriteriaSpecification;\n":"");
		content = content.replace("IMPORT_DATEUTIL", importDateUtil?"import org.apache.poi.ss.usermodel.DateUtil;\n":"");
		File file = new File(Common.SAVE_PATH+File.separator+"dao");
		if(!file.exists()){
			file.mkdirs();
		}
		Common.write(new File(file,Common.DAO_NAME+".java"), content);
		
		System.out.println(Common.DAO_NAME+".java 已生成.....");
	}
	
	private static String create_Method_findPageBy(){
		StringBuffer sb = new StringBuffer();
		sb.append(Common.getMethodDesc("分页查询","queryObj"));
		sb.append("\t").append("public IPage<"+Common.DOMAIN_NAME+"> findPageBy(QueryObj queryObj) {\n")
		  .append("\t\t").append("DetachedCriteria dc = this.getQueryCondition(queryObj);\n")
		  .append("\t\t").append("return super.findPageBy(dc, queryObj.getPageSize(), queryObj.getPageIndex());\n")
		  .append("\t}\n\n");
		sb.append("\t").append("private DetachedCriteria getQueryCondition(QueryObj queryObj){\n")
		  .append("\t\t").append("DetachedCriteria dc = DetachedCriteria.forClass("+Common.DOMAIN_NAME+".class);\n")
		  .append("\t\t").append("if(queryObj != null){\n");
//		  sb.append("\t\t\t").append("if("+Common.PROP_NAME+".getDeptId() != null){\n");
//		  
//		  sb.append("\t\t\t").append("}\n");
//		  System.out.println("**"+Common.query_FIELD);
//		  System.out.println("**"+Common._DESC);
		sb.append("JOINS_TABLES");
		
		StringBuffer joinsTables = new StringBuffer();
		List<String> temp = new ArrayList<String>();
		for(int k=0;k<Common._DESC.size();k++){
			temp.add(Common._DESC.get(k));
		}
		  //{HFLS_TS_JOB_STATE:JOB_NAME=true, HFLS_TS_JOB_STATE:JOB_STATE=true}
		
		int c = 97;
		for(int i=0;i<Common.QUERY.size();i++){
			int index = Common._FIELD.indexOf(Common.QUERY.get(i));
			if(index == -1) continue;
			String field = Common._FIELD.get(index);
			String fieldType = Common._TYPE.get(index);
			
			sb.append("\t\t\t//").append(Common._DESC.get(index)).append("\n");
			if(i == 0){
				sb.append("\t\t\t").append("String queryValue = queryObj.getQueryValue(\""+field+"\");").append("\n");
			}else{
				sb.append("\t\t\t").append("queryValue = queryObj.getQueryValue(\""+field+"\");").append("\n");
			}
			if(Common.MAPPING.containsKey(Common.TABLE_NAME+":"+Common._COLUMN.get(Common._FIELD.indexOf(Common.QUERY.get(i))))){
				  String mappingTableName = Common.MAPPING.get(Common.TABLE_NAME+":"+Common._COLUMN.get(Common._FIELD.indexOf(Common.QUERY.get(i)))).split(":")[0];
				  String mappingColumn = Common.MAPPING.get(Common.TABLE_NAME+":"+Common._COLUMN.get(Common._FIELD.indexOf(Common.QUERY.get(i)))).split(":")[1];
				  String mappingEntityName = Common.getEntityName(mappingTableName);
				  String mappingPropName = (mappingEntityName.charAt(0)+"").toLowerCase()+mappingEntityName.substring(1);
//				  String getField = "get" + mappingEntityName+"()";
				  String fieldName = Common.getFieldName(mappingColumn);

				  List<String> keys = Common.primaryKeys.get(mappingTableName);
				  if(keys == null){
					  keys = dbUtils.getPrimaryKey(mappingTableName);
					  Common.primaryKeys.put(mappingTableName, keys);
				  }
				  sb.append("\t\t\t").append("if(StringUtils.isNotBlank(queryValue)){\n");
				  if(keys.indexOf(mappingColumn) != -1){
//					  sb.append("\t\t\t").append("if("+Common.PROP_NAME+"."+getField+" != null && "+Common.PROP_NAME+"."+getField+".getId() != null){\n");
//					  String column = Common.PRIMATY_KEY.get(Common.PRIMATY_KEY_COLUMN.indexOf(mappingColumn));
//					  sb.append("\t\t\t\t").append("dc.add(Restrictions.eq(\""+mappingPropName+".id\", "+Common.PROP_NAME+"."+getField+".getId()));\n");
					  if("Long".equals(fieldType)){
						  sb.append("\t\t\t\t").append("dc.add(Restrictions.eq(\""+mappingPropName+"."+fieldName+"\", Long.parseLong(queryValue)));\n");
					  }else if("Double".equals(fieldType)){
						  sb.append("\t\t\t\t").append("dc.add(Restrictions.eq(\""+mappingPropName+"."+fieldName+"\", Double.parseDouble(queryValue)));\n");
					  }else if("Integer".equals(fieldType)){
						  sb.append("\t\t\t\t").append("dc.add(Restrictions.eq(\""+mappingPropName+"."+fieldName+"\", Integer.parseInt(queryValue)));\n");
					  }else if("Date".equals(fieldType)){
						  importDateUtil = true;
						  sb.append("\t\t\t\t").append("dc.add(Restrictions.eq(\""+mappingPropName+"."+fieldName+"\", DateUtil.parseYYYYMMDDDate(queryValue)));\n");
					  }else{
						  sb.append("\t\t\t\t").append("dc.add(Restrictions.eq(\""+mappingPropName+"."+fieldName+"\", queryValue));\n");
					  }
				  }else{
					  importLeftJoin = true;
					  char ch = new Character((char) c++);
					  joinsTables.append("\t\t\t").append("dc.createCriteria(\""+mappingPropName+"\",\""+ch+"\",CriteriaSpecification.LEFT_JOIN);\n");
					  
//					  String getFieldName = "get"+(fieldName.charAt(0)+"").toUpperCase()+fieldName.substring(1)+"()";
//					  sb.append("\t\t\t").append("if("+Common.PROP_NAME+"."+getField+" != null && "+Common.PROP_NAME+"."+getField+"."+getFieldName+" != null){\n");
//					  sb.append("\t\t\t\t").append("dc.add(Restrictions.eq(\""+ch+"."+fieldName+"\", "+Common.PROP_NAME+"."+getField+"."+getFieldName+"));\n");
					  
					  if("Long".equals(fieldType)){
						  sb.append("\t\t\t\t").append("dc.add(Restrictions.eq(\""+ch+"."+fieldName+"\", Long.parseLong(queryValue)));\n");
					  }else if("Double".equals(fieldType)){
						  sb.append("\t\t\t\t").append("dc.add(Restrictions.eq(\""+ch+"."+fieldName+"\", Double.parseDouble(queryValue)));\n");
					  }else if("Integer".equals(fieldType)){
						  sb.append("\t\t\t\t").append("dc.add(Restrictions.eq(\""+ch+"."+fieldName+"\", Integer.parseInt(queryValue)));\n");
					  }else if("Date".equals(fieldType)){
						  importDateUtil = true;
						  sb.append("\t\t\t\t").append("dc.add(Restrictions.eq(\""+ch+"."+fieldName+"\", DateUtil.parseYYYYMMDDDate(queryValue)));\n");
					  }else{
						  sb.append("\t\t\t\t").append("dc.add(Restrictions.eq(\""+ch+"."+fieldName+"\", queryValue));\n");
					  }
				  }
				  sb.append("\t\t\t").append("}\n");
			}else{
//				  String getField = "get"+(field.charAt(0)+"").toUpperCase()+field.substring(1)+"()";
//				  String trim= Common._TYPE.get(index).equals("String")?".trim()":"";
//				  if("".equals(trim)){
//					  sb.append("\t\t\t").append("if("+Common.PROP_NAME+"."+getField+" != null){\n");
//				  }else{
//					  sb.append("\t\t\t").append("if(StringUtils.isNotBlank("+Common.PROP_NAME+"."+getField+")){\n");
//				  }
//				  sb.append("\t\t\t\t").append("dc.add(Restrictions.eq(\""+field+"\", "+Common.PROP_NAME+"."+getField+"));\n")
//				    .append("\t\t\t").append("}\n");
				  
				  
				  sb.append("\t\t\t").append("if(StringUtils.isNotBlank(queryValue)){\n");
				  if("Long".equals(fieldType)){
					  sb.append("\t\t\t\t").append("dc.add(Restrictions.eq(\""+field+"\", Long.parseLong(queryValue)));\n");
				  }else if("Double".equals(fieldType)){
					  sb.append("\t\t\t\t").append("dc.add(Restrictions.eq(\""+field+"\", Double.parseDouble(queryValue)));\n");
				  }else if("Integer".equals(fieldType)){
					  sb.append("\t\t\t\t").append("dc.add(Restrictions.eq(\""+field+"\", Integer.parseInt(queryValue)));\n");
				  }else if("Date".equals(fieldType)){
					  importDateUtil = true;
					  sb.append("\t\t\t\t").append("dc.add(Restrictions.eq(\""+field+"\", DateUtil.parseYYYYMMDDDate(queryValue)));\n");
				  }else{
					  sb.append("\t\t\t\t").append("dc.add(Restrictions.eq(\""+field+"\", queryValue));\n");
				  }
				  sb.append("\t\t\t").append("}\n");
			}
		}
		sb.append("\t\t").append("}\n");
		sb.append("\t\t").append("return dc;\n");
		sb.append("\t}\n\n");
		
		String str = sb.toString().replace("JOINS_TABLES", joinsTables);
		return str;
	}
	private static StringBuffer create_Method_list() {
		StringBuffer sb = new StringBuffer();
		buff.append(Common.getMethodDesc("导出","queryObj"));
		sb.append("\t").append("public List<"+Common.DOMAIN_NAME+"> listExport(QueryObj queryObj) {\n")
		  .append("\t\t").append("DetachedCriteria dc = this.getQueryCondition(queryObj);").append("\n")
		  .append("\t\t").append("return super.findBy(dc);\n")
		  .append("\t}\n\n");
		return sb;
	}
	
	public static void main(String[] args) {
		BuildDao.createInterface();
//		BuildDao.createClass();
		System.out.println(buff.toString());
	}
}
